package com.n.facedetectordemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.media.FaceDetector;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.n.facedetectordemo.databinding.ActivityFaceBinding;

import java.io.IOException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import pub.devrel.easypermissions.EasyPermissions;

public class FaceActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

    ActivityFaceBinding binding;

    FrameLayout rootView;

    private CircleCanvasView circleCanvasView;

    private Camera mCamera;

    private boolean isIdentify = false;

    private int previewWidth;

    private int previewHeight;

    // 由于FaceDetector检测的不稳定性和准确率，这里控制识别成功一定次数后才算真正的通过，也可以优化为连续识别成功，这样准确率更高
    private int passNum = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityFaceBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);

        rootView = (FrameLayout) getRootView(this);

        addMasking(rootView);

        if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE)) {
            startPreview();
            countDownTimer.start();
        } else {
            EasyPermissions.requestPermissions(this, "请允许相机权限进行人脸检测",
                    100, Manifest.permission.CAMERA,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE);
        }
    }

    /**
     * 获取界面根视图
     *
     * @param context 上下文环境
     * @return root-view
     */
    public static View getRootView(Activity context) {
        return ((ViewGroup) context.findViewById(android.R.id.content)).getChildAt(0);
    }

    /**
     * 增加圆形蒙层
     *
     * @param view
     */
    private void addMasking(FrameLayout view) {
        circleCanvasView = new CircleCanvasView(this);
        view.addView(circleCanvasView);
    }

    /**
     * 开始预览
     */
    private void startPreview() {
        SurfaceHolder holder = binding.surfaceView.getHolder();
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                mCamera = getCustomCamera();
                mCamera.setPreviewCallback((data, camera) -> {
                    // 是否已经检测成功，如果是则不继续检测
                    if (isIdentify) {
                        checkFaces(data, camera, surfaceHolder, this);
                    }
                });
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                if (mCamera != null) {
                    Camera.Parameters parameters = mCamera.getParameters();
                    // 选择合适的图片尺寸，必须是手机支持的尺寸
                    List<Camera.Size> sizeList = parameters.getSupportedPictureSizes();
                    // 如果sizeList只有一个我们也没有必要做什么了，因为就他一个别无选择
                    if (sizeList.size() > 1) {
                        for (int j = 0; j < sizeList.size(); j++) {
                            Camera.Size size = sizeList.get(j);
                            previewWidth = size.width;
                            previewHeight = size.height;
                        }
                    }
                    //设置照片的大小
                    parameters.setPictureSize(previewWidth, previewHeight);
                    mCamera.setParameters(parameters);
                    try {
                        mCamera.setPreviewDisplay(holder);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    CameraUtils.takePicture(new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                            CameraUtils.startPreview();
                            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                            if (bitmap != null) {
                                Log.i(">>>>", "here");
                                bitmap = ImageUtils.getRotatedBitmap(bitmap, 180);
                            }
                            Log.i(">>>>", "here2");
                            CameraUtils.startPreview();
                        }
                    });
                    //调用相机预览功能
                    mCamera.startPreview();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                if (null != mCamera) {
                    holder.removeCallback(this);
                    mCamera.setPreviewCallback(null);
                    //停止预览
                    mCamera.stopPreview();
                    mCamera.lock();
                    //释放相机资源
                    mCamera.release();
                    mCamera = null;
                }
            }
        });
    }

    /**
     * 获取打开相机
     *
     * @return
     */
    private Camera getCustomCamera() {
        if (null == mCamera) {
            //Camera.open()方法说明：2.3以后支持多摄像头，所以开启前可以通过getNumberOfCameras先获取摄像头数目，
            // 再通过 getCameraInfo得到需要开启的摄像头id，然后传入Open函数开启摄像头，
            // 假如摄像头开启成功则返回一个Camera对象
            try {

                mCamera = Camera.open(Camera.getNumberOfCameras() - 1);
                //预览画面默认是横屏的，需要旋转90度
                mCamera.setDisplayOrientation(90);
            } catch (Exception e) {
            }
        }
        return mCamera;
    }

    /**
     * 检测是否存在人脸
     *
     * @param data          YUI的图片字节
     * @param camera        相机
     * @param surfaceHolder
     * @param callback
     */
    private void checkFaces(byte[] data, Camera camera, SurfaceHolder surfaceHolder, SurfaceHolder.Callback callback) {
        Camera.Size size = camera.getParameters().getPreviewSize();
        Bitmap bitmap = new FastYUVtoRGB(FaceActivity.this).convertYUVtoRGB(data, size.width, size.height);
        Bitmap bp = rotateMyBitmap(bitmap);
        BitmapFactory.Options BitmapFactoryOptionsbfo = new BitmapFactory.Options();
        BitmapFactoryOptionsbfo.inPreferredConfig = Bitmap.Config.RGB_565;

        Bitmap bitmap565 = bp.copy(Bitmap.Config.RGB_565, true);
        Bitmap newBP = mergeBitmap(bitmap565, getViewBitmap());
//                    FaceDetector face_detector = new FaceDetector(bp.getWidth(), bp.getHeight(), 1);
        FaceDetector face_detector = new FaceDetector(newBP.getWidth(), newBP.getHeight(), 1);
        FaceDetector.Face[] faces = new FaceDetector.Face[1];
        int face_count = face_detector.findFaces(newBP, faces);
        Log.i(">>>face num", String.valueOf(face_count));
        if (face_count > 0) {
            if (passNum >= 3) {
                circleCanvasView.setSuccess();
                circleCanvasView.invalidate();
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        // todo
                        // 成功后停留一定时间跳转到下一页面
                    }
                };
                timer.schedule(task, 500);
            } else {
                passNum++;
            }
            Log.i(">>>人脸数", passNum + "");
        } else {
            Log.i(">>>人脸数", face_count + "");
        }
    }

    /**
     * 旋转相机预览图
     *
     * @param bmp
     * @return
     */
    public Bitmap rotateMyBitmap(Bitmap bmp) {
        //*****旋转一下
        Matrix matrix = new Matrix();
        matrix.postRotate(270);

        Bitmap nbmp2 = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);

        return nbmp2;
    }

    /**
     * 合并两张bitmap图片
     *
     * @param firstBitmap
     * @param secondBitmap
     * @return
     */
    private Bitmap mergeBitmap(Bitmap firstBitmap, Bitmap secondBitmap) {
        Bitmap bitmap = Bitmap.createBitmap(firstBitmap.getWidth(), firstBitmap.getHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(firstBitmap, new Matrix(), null);
        canvas.drawBitmap(secondBitmap, new Matrix(), null);
        return bitmap;
    }

    /**
     * 传入的activity是要截屏的activity
     */
    public Bitmap getViewBitmap() {
        View rootView = circleCanvasView;
        rootView.buildDrawingCache();

        //允许当前窗口保存缓存信息
        rootView.setDrawingCacheEnabled(true);
        //去掉状态栏高度
        Bitmap bitmap = Bitmap.createBitmap(rootView.getDrawingCache(), 0, 0, rootView.getWidth(), rootView.getHeight());
        return bitmap;
    }

    /**
     * CountDownTimer 实现倒计时
     */
    private CountDownTimer countDownTimer = new CountDownTimer(3000, 5000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            isIdentify = true;
        }
    };

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        startPreview();
        countDownTimer.start();
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Toast.makeText(this, "权限获取失败，无法进行检测，请开启相应权限~", Toast.LENGTH_SHORT).show();
    }
}